package com.raven.craft.code.generator.project.antijson;

import com.fasterxml.jackson.databind.JsonNode;
import com.raven.craft.code.generator.IGenerator;
import com.raven.craft.code.generator.common.file.HbsFile;
import com.raven.craft.code.generator.common.file.metadata.FileMetadata;
import com.raven.craft.code.generator.common.file.metadata.JavaFileMetadata;
import com.raven.craft.code.generator.common.util.JsonUtil;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * @author raven
 * @date 2020/08/29
 **/
@Slf4j
@Getter
@ToString
@ConditionalOnProperty(prefix = "generator.project.anti-json", name = "enabled", havingValue = "true", matchIfMissing = true)
@Component
public class AntiJsonGenerator implements IGenerator {

    private final AntiJsonProperties properties;

    public AntiJsonGenerator(AntiJsonProperties properties) {
        this.properties = properties;
    }

    @SneakyThrows
    private static JsonNode getJsonNode(AntiJsonProperties properties) {
        String json;
        if (properties.getJsonURL().startsWith("http")) {
            json = getJsonByUrl(properties.getJsonURL());
        } else {
            json = String.join("\n", Files.readAllLines(Paths.get(properties.getJsonURL())));
        }
        return JsonUtil.getMapper().readTree(json);
    }

    private static String getJsonByUrl(String url) {
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class);

        if (entity.getStatusCode().isError()) {
            throw new RuntimeException(String.format("get json by url[%s] failed. code: %s, message: %s", url, entity.getStatusCode().toString(), entity.getBody()));
        }
        return entity.getBody();
    }

    private static HbsFile createAntiJsonFile(JsonNode jsonNode, AntiJsonProperties properties) {
        FileMetadata metadata = new JavaFileMetadata(properties.getRootTypeName(), properties.getTargetDir(), properties.getTargetPackage());
        AntiJsonVo vo = new AntiJsonVo(jsonNode, properties);
        return new HbsFile(metadata, properties.getTemplatePath(), vo);
    }

    @Override
    public void generate() {
        log.info("begin to generate anti json file");
        JsonNode jsonNode = getJsonNode(properties);

        createAntiJsonFile(jsonNode, properties).output();
    }
}
